#define WIN32_LEAN_AND_MEAN  /* required by xmlrpc-c/server_abyss.hpp */

#include <cassert>
#include <stdexcept>
#include <iostream>
#ifdef _WIN32
#  include <windows.h>
#else
#  include <unistd.h>
#endif

#include <xmlrpc-c/base.hpp>
#include <xmlrpc-c/registry.hpp>
#include <xmlrpc-c/server_abyss.hpp>

#ifdef _WIN32
#define SLEEP(seconds) SleepEx(seconds * 1000);
#else
#define SLEEP(seconds) sleep(seconds);
#endif
#include "depth.cc"

using namespace std;

class sampleAddMethod : public xmlrpc_c::method {
public:
	sampleAddMethod() {
		// signature and help strings are documentation -- the client
		// can query this information with a system.methodSignature and
		// system.methodHelp RPC.
		this->_signature = "i:ii";
		// method's result and two arguments are integers
		this->_help = "This method adds two integers together";
	}
	void
		execute(xmlrpc_c::paramList const& paramList,
			xmlrpc_c::value* const  retvalP) {

		int const addend(paramList.getInt(0));
		int const adder(paramList.getInt(1));

		paramList.verifyEnd(2);
		int depvalue = getDepth(addend, adder);
		*retvalP = xmlrpc_c::value_int(depvalue);

		// Sometimes, make it look hard (so client can see what it's like
		// to do an RPC that takes a while).
		// if (adder == 1)
		//     SLEEP(2);
	}
};

class test : public xmlrpc_c::method {
public:
	test() {
		// signature and help strings are documentation -- the client
		// can query this information with a system.methodSignature and
		// system.methodHelp RPC.
		this->_signature = "i:ii";
		// method's result and two arguments are integers
		this->_help = "This method adds two integers together";
	}
	void
		execute(xmlrpc_c::paramList const& paramList,
			xmlrpc_c::value* const  retvalP) {
		std::cout << "canshu: " << std::endl;
		int const addend(paramList.getInt(0));
		int const adder(paramList.getInt(1));
		std::cout << addend << std::endl;
		std::cout << adder << std::endl;

		paramList.verifyEnd(2);
		int depvalue = addend + adder;
		std::cout << depvalue << std::endl;
		*retvalP = xmlrpc_c::value_int(depvalue);

		// Sometimes, make it look hard (so client can see what it's like
		// to do an RPC that takes a while).
		// if (adder == 1)
		//     SLEEP(2);
	}
};

class test2 : public xmlrpc_c::method {
public:
	test2() {
	}
	void
		execute(xmlrpc_c::paramList const& paramList,
			xmlrpc_c::value* const  retvalP) {
		int depvalue = 12;
		std::cout << depvalue << std::endl;
		*retvalP = xmlrpc_c::value_int(depvalue);

	}
};

int main(int const,const char** const) {

	try {
		xmlrpc_c::registry myRegistry;
		xmlrpc_c::methodPtr const sampleAddMethodP(new sampleAddMethod);
		myRegistry.addMethod("get_depth", sampleAddMethodP);
		xmlrpc_c::methodPtr const sampletest(new test);
		myRegistry.addMethod("test", sampletest);
		xmlrpc_c::methodPtr const sampletest2(new test2);
		myRegistry.addMethod("test2", sampletest2);
		xmlrpc_c::serverAbyss myAbyssServer(
			xmlrpc_c::serverAbyss::constrOpt()
			.registryP(&myRegistry)
			.portNumber(8184));

		cout << "starting" << endl;
		myAbyssServer.run();
		// xmlrpc_c::serverAbyss.run() never returns
		assert(false);
	}
	catch (exception const& e) {
		cout << "14" << endl;
		cerr << "Something failed.  " << e.what() << endl;
	}
	return 0;
}